/*
 * Copyright 2007. Mount Sinai Hospital, Toronto, Canada.
 * 
 * Licensed under the GNU Lesser General Public License, Version 2. You
 * can find a copy of the license at:
 * 
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 * 
 * IN NO EVENT SHALL MOUNT SINAI HOSPITAL BE LIABLE TO ANY PARTY FOR DIRECT, 
 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST 
 * PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 
 * EVEN IF MOUNT SINAI HOSPITAL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
 * DAMAGE.
 * 
 * MOUNT SINAI HOSPITAL SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND 
 * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". 
 * MOUNT SINAI HOSPITAL HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, 
 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
 */
package com.sinai.mshab.client.pages;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sinai.mshab.client.ui.aggregate.Page;
import com.sinai.mshab.client.ui.aggregate.PageContainer;
import com.sinai.mshab.client.ui.basic.PasswordComponent;
import com.sinai.mshab.client.ui.basic.TextQuestionComponent;
import com.sinai.mshab.client.user.UserValidator;

/**
 * This page allows users to login.
 * 
 * @author serge
 * 
 */
public class Login extends Page implements KeyboardListener {

	private TextQuestionComponent username;

	private PasswordComponent password;

	private String redirectPage;

	private UserValidator user_validator;

	public static PageContainer container_static;

	public static String redirectPage_static;

	public boolean showForgotPasswordLink = true;

	public boolean showRegisterLink = true;

	/**
	 * Creates a new login page
	 * 
	 * @param page_container
	 *            the page container to put this page in
	 * @param redirectPage
	 *            the page which will be loaded after logging in
	 */
	public Login(PageContainer page_container, String redirectPage,
			UserValidator user_validator) {
		super(page_container);
		this.user_validator = user_validator;
		this.redirectPage = redirectPage;
		redirectPage_static = redirectPage;
	}

	public void initialize() {

		container.getEastPanel().setVisible(false);
		container.getWestPanel().setVisible(false);

		container_static = container;

		// main horizontal panel containing 2 secions, login and register
		HorizontalPanel hpanel = new HorizontalPanel();

		// login vertical panel
		VerticalPanel vpanel_login = new VerticalPanel();

		// register vertical panel
		VerticalPanel vpanel_register = new VerticalPanel();

		// adding a title
		Label title = new Label("User Login");
		title.setStyleName("h3");

		// The explanation of survey
		Label greeting = new Label(
				"Please login with your username and password.");
		greeting.setStyleName("explanation");

		username = new TextQuestionComponent("username", "users", "Username:",
				"", "Please specify your username");
		password = new PasswordComponent("password", "users", "Password:", "",
				"Please type your password");

		username.setDescriptionStyleName("description_label_short");
		password.setDescriptionStyleName("description_label_short");

		password.addKeyboardListener(this);

		Label forgot_label = new Label("Forgot your password?");
		forgot_label.setStyleName("light_link");
		forgot_label.addClickListener(new ForgotListener());

		// the login button
		Button login_button = new Button("Login");
		login_button.addClickListener(new LoginListener());
		login_button.setStyleName("login_button");

		// Don't have an account?
		Label no_account_label = new Label("Don't have an account?");
		no_account_label.setStyleName("h3");
		Label register_desc_label = new Label("Register a new account: ");
		register_desc_label.setStyleName("explanation");

		// the register button
		Button register_button = new Button("Register");
		register_button.addClickListener(new RegisterListener());
		register_button.setStyleName("register_button_on_login");

		// adding things to the login vpanel
		vpanel_login.add(title);
		vpanel_login.add(greeting);
		vpanel_login.add(username);
		vpanel_login.add(password);
		if (showForgotPasswordLink) {
			vpanel_login.add(forgot_label);
		}
		vpanel_login.add(login_button);

		// adding things to the register vpanel
		vpanel_register.add(no_account_label);
		vpanel_register.add(register_desc_label);
		vpanel_register.add(register_button);

		// add css tags
		vpanel_login.setStyleName("lightshadebox");
		vpanel_register.setStyleName("lightshadebox");

		// adding the vpanels to the hpanel.
		hpanel.add(vpanel_login);
		if (showRegisterLink) {
			hpanel.add(vpanel_register);
		}
		
		// adding everything to the page.
		this.add(hpanel);

		this.setWidth("600px");
	}
	
	public void hideForgotPasswordLink() {
		showForgotPasswordLink = false;
	}
	
	public void hideRegisterLink() {
		showRegisterLink = false;
	}

	/**
	 * This listener is attached to the button that retrieves passwords
	 */
	private class ForgotListener implements ClickListener {
		public void onClick(Widget sender) {
			container.loadPage("Forgot Password");
		}
	}

	/**
	 * This listener is attached to the button that registers new users.
	 */
	private class RegisterListener implements ClickListener {
		public void onClick(Widget sender) {
			container.loadPage("Register");
		}
	}

	/**
	 * This listener is attached to the button that logins users.
	 */
	private class LoginListener implements ClickListener {
		public void onClick(Widget sender) {
			checkLogin();
		}
	}

	/**
	 * Sends username and password to database to check if it's valid.
	 */
	private void checkLogin() {
		String user = username.getAnswer().getFirstAnswer();
		String pass = password.getAnswer().getFirstAnswer();
		user_validator.authenticate(user, pass);
	}

	/**
	 * This method is called when the UserValidator has decided that the
	 * provided user is valid.
	 */
	public static void userIsValid() {
		container_static.loadPage(redirectPage_static);
	}

	/**
	 * The keyboard listener for the password box. Listens for the ENTER key and
	 * submits the login ingo upon the enter key.
	 */
	public void onKeyPress(Widget sender, char keyCode, int modifiers) {
		// hitting enter key is equivalent to clicking Login button.
		if ((int) keyCode == 13) {
			checkLogin();
		}
	}

	/**
	 * Unused keyboard listener for password box.
	 */
	public void onKeyDown(Widget sender, char keyCode, int modifiers) {

	}

	/**
	 * Unused keyboard listener for password box.
	 */
	public void onKeyUp(Widget sender, char keyCode, int modifiers) {

	}
}
